home *** CD-ROM | disk | FTP | other *** search
- /*------------------------------------------------------------------*/
- /* */
- /* MC68000 Cross Assembler */
- /* */
- /* Copyright (c) 1985 by Brian R. Anderson */
- /* */
- /* Main program - September 9, 1987 */
- /* */
- /* This program may be copied for personal, non-commercial use */
- /* only, provided that the above copyright notice is included */
- /* on all copies of the source code. Copying for any other use */
- /* without the consent of the author is prohibited. */
- /* */
- /*------------------------------------------------------------------*/
- /* */
- /* Originally published (in Modula-2) in */
- /* Dr. Dobb's Journal, April, May, and June 1986. */
- /* */
- /* AmigaDOS conversion copyright (c) 1987 by Charlie Gibbs. */
- /* */
- /*------------------------------------------------------------------*/
-
- char Version[] = "1.02 (September 9, 1987)";
-
-
- #include <stdio.h>
- #define PRIMARY
- #include "a68kdef.h"
- #include "a68kglb.h"
-
-
- /********************************************************************/
- /* */
- /* NOTE: the following line, plus any additional references */
- /* to _fmode, is inserted to make this program work under */
- /* the MS-DOS version of Lattice C. It is not necessary */
- /* for the Amiga version, but does no harm if left in. */
- /* */
- /********************************************************************/
- int _fmode = 0; /* File mode - 0x8000 for binary */
-
-
-
- /* Functions */
- extern int LineParts(), GetField(), Instructions(), ObjDir();
- extern int GetSize(), GetInstModeSize(), GetMultReg();
- extern int ReadSymTab(), GetArgs(), GetAReg(), OpenIncl();
- extern long AddrBndW(), AddrBndL(), GetValue(), CalcValue();
- #ifdef AZTEC_C
- extern char *lmalloc();
- #else
- extern char *malloc();
- #endif
- extern FILE *fopen();
-
-
-
- main(argc,argv) int argc; char *argv[];
- {
- char ListFN[MAXFN], SrecFN[MAXFN], EquateFN[MAXFN]; /* File names */
- int MakeEqu; /* Create an equate file */
- FILE *EquFile; /* Equate file pointer */
- int endfile; /* End-of-file flag */
- long maxheap, maxheap2; /* Maximum heap sizes */
- int cmderror, dummy;
- long templong;
- register struct SymTab *sym;
- register int i, j;
-
- cmderror = FALSE; /* Clear command-line error flag */
- SourceFN[0] = '\0'; /* Don't have source name yet */
- HeaderFN[0] = EquateFN[0] = '\0'; /* No header or equate files yet */
- ListFN[0] = SrecFN[0] = '\0'; /* Indicate default file names */
- InclList[0] = '\0'; /* Clear the include directory list */
- IdntName[0] = '\0'; /* Clear program unit name */
- LnMax = 60;
- XrefList = DumpSym = GotEqur = MakeEqu = FALSE;
- SuppList = TRUE; /* Default to no listing file */
- maxheap = DEFHEAP; /* Primary heap size default */
- maxheap2 = DEFHEAP2; /* Secondary heap size default */
-
- printf ("\n68000 Cross Assembler\n");
- printf ("Copyright (c) 1985 by Brian R. Anderson\n\n");
- printf ("AmigaDOS conversion copyright (c) 1987 by Charlie Gibbs.\n");
- printf ("Version %s\n\n", Version);
-
- for (i = 1; i < argc; i++) { /* Analyze command line */
- if (argv[i][0] != '-') {
- if (SourceFN[0] == '\0')
- strcpy (SourceFN, argv[i]); /* Source file name */
- else if (SrecFN[0] == '\0')
- strcpy (SrecFN, argv[i]); /* Object file name */
- else if (ListFN[0] == '\0')
- strcpy (ListFN, argv[i]); /* Listing file name */
- else {
- printf ("Too many file names.\n");
- cmderror = TRUE;
- }
- } else {
- switch (argv[i][1]) {
- case 'D':
- case 'd':
- DumpSym = TRUE;
- if (argv[i][2]) {
- printf ("Invalid symbol table dump switch.\n");
- cmderror = TRUE;
- }
- break;
- case 'E': /* Equate file name */
- case 'e':
- MakeEqu = TRUE;
- if (EquateFN[0]) {
- printf ("Equate file is declared more than once.\n");
- cmderror = TRUE;
- } else if (argv[i][2])
- strcpy (EquateFN, &argv[i][2]);
- break;
- case 'H': /* Header file name */
- case 'h':
- if (HeaderFN[0]) {
- printf ("Header file is declared more than once.\n");
- cmderror = TRUE;
- } else if (argv[i][2]) {
- strcpy (HeaderFN, &argv[i][2]);
- } else {
- printf ("Header file name is missing\n");
- cmderror = TRUE;
- }
- break;
- case 'I': /* Include directories */
- case 'i':
- if (argv[i][2]) {
- if (InclList[0])
- strcat (InclList, ","); /* Add to previous list */
- strcat (InclList, &argv[i][2]);
- } else {
- printf ("Include directory list is missing.\n");
- cmderror = TRUE;
- }
- break;
- case 'L': /* Listing file name */
- case 'l':
- SuppList = FALSE; /* Produce a listing */
- if (ListFN[0]) {
- printf ("List file is declared more than once.\n");
- cmderror = TRUE;
- } else if (argv[i][2])
- strcpy (ListFN, &argv[i][2]);
- break;
- case 'O': /* Object file name */
- case 'o':
- if (SrecFN[0]) {
- printf ("Object file is declared more than once.\n");
- cmderror = TRUE;
- } else if (argv[i][2]) {
- strcpy (SrecFN, &argv[i][2]);
- } else {
- printf ("Object file name is missing\n");
- cmderror = TRUE;
- }
- break;
- case 'P':
- case 'p':
- if ((LnMax = CalcValue(&argv[i][2], 0)) < 10) {
- printf ("Invalid page depth.\n");
- cmderror = TRUE;
- }
- break;
- case 'S':
- case 's':
- SFormat = TRUE;
- if (argv[i][2]) {
- printf ("Invalid S-format switch.\n");
- cmderror = TRUE;
- }
- break;
- case 'W':
- case 'w':
- if (argv[i][2] != ',') {
- maxheap = CalcValue(&argv[i][2], 0);
- if (maxheap < MAXLINE)
- maxheap = MAXLINE; /* Minimum heap size */
- maxheap &= ~3L; /* Long-word alignment */
- }
- for (j = 2; argv[i][j]; j++) {
- if (argv[i][j] == ',') { /* Find secondary size */
- maxheap2 = CalcValue(&argv[i][j+1], 0);
- if (maxheap2 < MAXLINE) {
- maxheap2 = MAXLINE;
- }
- maxheap2 &= ~3L;
- break;
- }
- }
- break;
- case 'X':
- case 'x':
- XrefList = TRUE;
- SuppList = FALSE; /* We must want a listing */
- if (argv[i][2]) {
- printf ("Invalid cross-reference switch.\n");
- cmderror = TRUE;
- }
- break;
- default:
- printf ("Unrecognized switch.\n");
- cmderror = TRUE;
- break;
- }
- }
- }
-
- if (SourceFN[0] == '\0') { /* Default list file name */
- printf ("Source file name is missing.\n");
- cmderror = TRUE;
- }
-
- if (EquateFN[0] == '\0') { /* Default equate file name */
- strcpy (EquateFN, SourceFN);
- i = strlen (EquateFN);
- while (--i > 0) {
- if (EquateFN[i] == '.') {
- EquateFN[i] = '\0'; /* Chop off name extension */
- break;
- }
- }
- strcat (EquateFN, ".equ"); /* Equate file name extension */
- }
-
- if (ListFN[0] == '\0') { /* Default list file name */
- strcpy (ListFN, SourceFN);
- i = strlen (ListFN);
- while (--i > 0) {
- if (ListFN[i] == '.') {
- ListFN[i] = '\0'; /* Chop off name extension */
- break;
- }
- }
- strcat (ListFN, ".lst"); /* List file name extension */
- }
-
- if (SrecFN[0] == '\0') { /* Default object file name */
- strcpy (SrecFN, SourceFN);
- i = strlen (SrecFN);
- while (--i > 0) {
- if (SrecFN[i] == '.') {
- SrecFN[i] = '\0'; /* Chop off name extension */
- break;
- }
- }
- if (SFormat)
- strcat (SrecFN, ".s"); /* S-format name extension */
- else
- strcat (SrecFN, ".o"); /* AmigaDOS format extension */
- }
-
- if (strcmp (SourceFN, EquateFN) == 0) {
- printf ("Source and equate file names are the same.\n");
- cmderror = TRUE;
- }
- if (strcmp (SourceFN, ListFN) == 0) {
- printf ("Source and listing file names are the same.\n");
- cmderror = TRUE;
- }
- if (strcmp (SourceFN, SrecFN) == 0) {
- printf ("Source and object file names are the same.\n");
- cmderror = TRUE;
- }
- if (strcmp (EquateFN, ListFN) == 0) {
- printf ("Equate and listing file names are the same.\n");
- cmderror = TRUE;
- }
- if (strcmp (EquateFN, SrecFN) == 0) {
- printf ("Equate and object file names are the same.\n");
- cmderror = TRUE;
- }
- if (strcmp (ListFN, SrecFN) == 0) {
- printf ("Listing and object file names are the same.\n");
- cmderror = TRUE;
- }
-
- /* Open Files. */
-
- _fmode = 0x8000; /****** MS-DOS only ******/
- if (!cmderror) {
- if ((InFile = fopen (SourceFN, "r")) == NULL) {
- printf ("Unable to open source file.\n");
- cmderror = TRUE;
- }
- }
- _fmode = 0; /****** MS-DOS only ******/
- if (!cmderror && MakeEqu) {
- if ((EquFile = fopen (EquateFN, "w")) == NULL) {
- printf ("Unable to open equate file.\n");
- cmderror = TRUE;
- fclose (InFile); /* Close any opened files */
- }
- }
- if (!cmderror && !SuppList) {
- if ((List = fopen (ListFN, "w")) == NULL) {
- printf ("Unable to open listing file.\n");
- cmderror = TRUE;
- fclose (InFile);
- if (MakeEqu)
- fclose (EquFile);
- }
- }
- if (!SFormat) _fmode = 0x8000; /****** MS-DOS only ******/
- if (!cmderror) {
- if ((Srec = fopen (SrecFN, "w")) == NULL ) {
- printf ("Unable to open object code file.\n");
- cmderror = TRUE;
- fclose (InFile);
- if (MakeEqu)
- fclose (EquFile);
- if (!SuppList)
- fclose (List);
- }
- }
-
- if (cmderror) {
- printf ("\n");
- printf ("Usage: a68k <source file>\n");
- printf (" [-e<equate file>]\n");
- printf (" [-h<header file>]\n");
- printf (" [-i<include dirlist>]\n");
- printf (" [-l<listing file>]\n");
- printf (" [-o<object file>]\n");
- printf (" [-p<page depth>]\n");
- printf (" [-w[<heap size>][,<heap size>]]\n");
- printf (" [-d] [-s] [-x]\n\n");
- printf ("Command-line arguments can appear in any order.\n");
- printf ("Heap size default (bytes): -w");
- printf ("%ld,%ld\n", (long) DEFHEAP, (long) DEFHEAP2);
- printf ("\n");
- exit(20);
- }
-
- #ifdef AZTEC_C
- Heap = lmalloc (maxheap);
- #else
- Heap = malloc ((unsigned) maxheap);
- #endif
- if (Heap == NULL) {
- printf ("Unable to allocate primary heap!\n");
- exit(20);
- }
- HeapLim = Heap; /* Heap limit (start out empty) */
- LowHeap = (Heap + maxheap);
- SymStart = (struct SymTab *) (LowHeap); /* Symbol table */
-
- #ifdef AZTEC_C
- Heap2 = lmalloc (maxheap2);
- #else
- Heap2 = malloc ((unsigned) maxheap2);
- #endif
- if (Heap2 == NULL) {
- printf ("Unable to allocate secondary heap!\n");
- exit(20);
- }
- NextFNS = Heap2;
- InF = (struct InFCtl *) (Heap2 + maxheap2);
- LowInF = --InF;
- InFNum = OuterMac = SkipNest = InF->Pos = InF->MCnt = 0;
- InF->Line = 0;
- InF->UPtr = 0;
- InF->NPtr = NextFNS;
- InF->NArg = -1;
- strcpy (NextFNS, SourceFN);
- NextFNS += strlen (SourceFN) + 1;
- High2 = NextFNS;
- Low2 = (char *) LowInF;
-
- _fmode = 0x8000; /****** MS-DOS only ******/
- printf ("\nAssembling %s\n\n\n", SourceFN);
-
- /*-------------------------------------------------------------------
-
- Begin Pass 1.
- */
- printf ("PASS 1\n");
- LineCount = LabLine = MacCount = ErrorCount = NumSyms = 0;
- AddrCnt = SectStart = 0L; /* Assume ORG = 0 to start */
- CurrHunk = NextHunk = 0L; /* Start in hunk zero */
- HunkType = HunkNone; /* We're not in a hunk yet */
- HunkFlags = SectLine = 0;
- endfile = ListOff = Pass2 = FALSE;
-
- while (!endfile && (strcmp (OpCode, "END") != 0)) {
- PrevDir = Dir; /* Save previous directive */
- endfile = LineParts (dummy); /* Get a statement */
- Dir = ObjDir (Srec); /* Process directives */
- GetObjectCode (dummy); /* Length if executable */
-
- if ((HunkType == HunkNone) && (AddrAdv != 0)) {
- Sym = SymStart; /* Insert at head of table */
- templong = (long) HunkCode << 16;
- AddSymTab (" ", 0L, templong, LineCount, 16);
- Sect = Sym; /* Create an unnamed section */
- HunkType = HunkCode;
- SectLine = LineCount;
- NextHunk++;
- }
- if ((Label[0] != '\0')
- && (Dir != Set) && (Dir != Equr) && (Dir != Reg)) {
- if (!ReadSymTab (Label)) { /* Make a new entry */
- AddSymTab (Label, AddrCnt, CurrHunk, LineCount, 0);
- } else if ((Sym->Flags & 1) /* If dup., ignore */
- || (Sym->Defn == 0)) { /* else fill in */
- Sym->Val = AddrCnt; /* Current loc. */
- Sym->Hunk = CurrHunk; /* Hunk number */
- Sym->Defn = LineCount; /* Statement number */
- Sym->Flags &= ~1; /* Clear XREF flag */
- }
- if (Dir == Equ) {
- Sym->Val = ObjSrc; /* Equated value */
- Sym->Hunk = Src.Hunk; /* Hunk number */
- }
- }
- AddrCnt += AddrAdv; /* Advance location counter */
- }
-
-
- /*----------------------------------------------------------------
-
- Begin Pass 2.
- */
- printf ("PASS 2\n");
- InF = (struct InFCtl *) (Heap2 + maxheap2);
- InF--;
- InFNum = OuterMac = SkipNest = InF->Pos = InF->MCnt = 0;
- InF->Line = 0;
- InF->UPtr = 0;
- InF->NPtr = Heap2;
- InF->NArg = -1;
- fclose (InFile); /* "Rewind" the source file */
- InFile = fopen (SourceFN, "r");
- NextFNS = Heap2 + strlen (SourceFN) + 1;
- Pass2 = TRUE;
- LineCount = LabLine = MacCount = ErrorCount = 0;
- AddrCnt = CurrHunk = SectStart = EndAddr = 0L;
- HunkType = HunkNone;
- HunkFlags = SectLine = 0;
- endfile = ListOff = FALSE;
- if ((Sym = SymStart) < (struct SymTab *) (Heap + maxheap)) {
- while (Sym->Flags & 16) {
- Sym->Val = 0L; /* Back to start of all sections */
- Sym++;
- }
- }
- TTLstring[0] = '\0'; /* Clear title string */
- if ((templong = (HeapLim - Heap) & 3L) != 0)
- HeapLim += 4 - templong;
- HighHeap = HeapLim; /* High-water mark in heap */
- RelStart = (struct RelTab *) HeapLim; /* Relocation table */
- RefStart = (struct Ref *) SymStart; /* Cross-reference table */
-
- /* Sign on messages for listing file */
- LnCnt = 999;
- PgCnt = 0;
- TTLstring[0] = '\0';
- if (!SuppList) {
- CheckPage (List, FALSE); /* Print headings */
- fprintf (List, "68000 Cross Assembler\n");
- fprintf (List, "Copyright (c) 1985 by Brian R. Anderson\n\n");
- fprintf (List, "AmigaDOS conversion copyright (c) 1987");
- fprintf (List, " by Charlie Gibbs.\n");
- fprintf (List, "Version %s\n\n", Version);
- LnCnt += 6;
- }
-
- StartSrec (Srec, IdntName); /* Write object header record */
-
- /* Process the second pass. */
-
- OpCode[0] = '\0'; /* Kill "END" from pass 1! */
- while (!endfile && (strcmp(OpCode,"END") != 0)) {
- PrevDir = Dir; /* Save previous directive */
- endfile = LineParts (dummy); /* Get a statement */
- if (!endfile) {
- Dir = ObjDir (Srec); /* Process directives */
- GetObjectCode (dummy); /* Executable object code */
- if (Label[0] != '\0') { /* If statement is labeled, */
- ReadSymTab (Label); /* check for duplicate defn. */
- if (Sym->Defn != LineCount) {
- AddRef (LineCount); /* Got one - flag as reference */
- if (Dir == Set) {
- if ((Sym->Flags & 4) == 0)
- Error (0, SymDup); /* Can't SET normal label */
- } else {
- Error (0, SymDup); /* Ordinary duplicate */
- }
- } else if (Dir == Set) {
- AddRef (LineCount); /* Flag all SETs as references */
- } else {
- if (Sym->Val != AddrCnt)
- if ((Dir != Equ) && (Dir != Equr) && (Dir != Reg))
- Error (0, Phase); /* Assembler error */
- }
- }
- if (!SuppList)
- WriteListLine (List);
- WriteSrecLine (Srec);
- AddrCnt += AddrAdv; /* Advance locaton counter */
- } else {
- Error (0, EndErr); /* END statement is missing */
- if (!SuppList)
- WriteListLine (List);
- }
- }
-
- /*---------------------------------------------------------------------
-
- Clean up.
- */
-
- fclose (InFile); /* Finished with source file */
-
- EndSdata (Srec, EndAddr); /* Write remaining data and end record */
- fclose (Srec); /* Finished with object file */
-
- if (XrefList)
- WriteSymTab (List); /* List the symbol table */
-
- /* Write all absolute symbols to an equate file if desired. */
- if (MakeEqu) {
- fprintf (EquFile, "* Equate file for %s\n", SourceFN);
- fprintf (EquFile, "* Created by A68k version %s\n", Version);
- for (i = 0, sym = SymStart; i < NumSyms; i++, sym++) {
- if (((sym->Hunk & 0x00007FFFL) == ABSHUNK)
- && ((sym->Flags == 0) || (sym->Flags == 2))) {
- fprintf (EquFile, "%s\tEQU\t$", sym->Nam);
- LongPut (EquFile, sym->Val, 4);
- fprintf (EquFile, "\n");
- }
- }
- fclose (EquFile);
- }
-
- /* Write error count to console and listing file. */
- printf (" \n\nEnd of assembly - ");
- if (!SuppList)
- fprintf (List, "\n\nEnd of assembly - ");
- if (ErrorCount == 0) {
- printf ("no errors were found.\n\n");
- if (!SuppList)
- fprintf (List, "no errors were found.\n\n");
- } else if (ErrorCount == 1) {
- printf ("1 error was found.\n\n");
- if (!SuppList)
- fprintf (List, "1 error was found.\n\n");
- } else {
- printf ("%d errors were found.\n\n", ErrorCount);
- if (!SuppList)
- fprintf (List, "%d errors were found.\n\n", ErrorCount);
- }
- templong = (long) (HighHeap - Heap);
- if (LowHeap < (char *) RefStart)
- templong += (long) (Heap + maxheap - LowHeap);
- else
- templong += (long) (Heap + maxheap - (char *) RefStart);
- printf ("Heap usage (bytes): -w%ld", templong);
- if (!SuppList)
- fprintf (List, "Heap usage (bytes): -w%ld", templong);
- templong = (long) (High2 - Heap2);
- if (Low2 < (char *) LowInF)
- templong += (long) (Heap2 + maxheap2 - Low2);
- else
- templong += (long) (Heap2 + maxheap2 - (char *) LowInF);
- printf (",%ld\n\n", templong);
- if (!SuppList) {
- fprintf (List, ",%ld\n\f", templong); /* One last page eject */
- fclose (List); /* Finished with listing file */
- }
- free (Heap); /* Release heap space */
- free (Heap2);
- exit (ErrorCount ? 10 : 0); /* All done */
- }
-